package org.dromara.bean.service.impl;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;

import lombok.extern.slf4j.Slf4j;

import org.dromara.bean.config.AppTypeConfig;
import org.dromara.bean.config.WxPaymentConfig;
import org.dromara.bean.constant.CommonConstant;
import org.dromara.bean.domain.HisPaymentLog;
import org.dromara.bean.domain.pay.OrderModel;
import org.dromara.bean.domain.pay.WxNativePayRequest;
import org.dromara.bean.service.*;
import org.dromara.bean.util.wxApi.WXPay;
import org.dromara.bean.util.wxApi.WXPayUtil;
import org.dromara.bean.util.wxApi.WeChatUtil;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.service.DictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * @Description:支付
 * @Author: ll
 * @Date: 2020-11-01
 * @Version: V1.0
 */
@Slf4j
@Service

public class BasePaymentServiceImpl implements IBasePaymentService {


    @Autowired
    private IBasePaymentLogService paymentLogService;

    @Autowired
    private DictService baseDictService;

    @Autowired
    private IBaseWechatService iBaseWechatService;





    /**
     * 微信支付—>统一下单
     *
     * @return
     */
    @Override
    public R<?> wxPay(OrderModel orderModel) {
        Map<String, String> returnResult = new HashMap();


        WxPaymentConfig wxPaymentConfig = baseDictService.getDictToObj("wx_pay_config", new WxPaymentConfig());
        log.debug("统一下单接口wxPaymentConfig: " + wxPaymentConfig.toString());
        //需要结合终端去判断
        JSONObject appInfoByType = null;
        //小程序
        appInfoByType = iBaseWechatService.getAppInfoByType(null);
        //app

//        log.debug("统一下单接口appInfoByType: " + appInfoByType.toString());

        wxPaymentConfig.setAppId(appInfoByType.getString("appId"));
        wxPaymentConfig.setAppSecret(appInfoByType.getString("appSecret"));
        Map<String, String> map;
        try {
            WXPay wxPay = new WXPay(wxPaymentConfig);

            log.warn("统一下单接口请求之前参数orderModel: " + orderModel.toString());
            log.debug("统一下单接口请求之前参数wxPaymentConfig: " + wxPaymentConfig.toString());
            map = WeChatUtil.unifiedOrderDataMap(orderModel, wxPaymentConfig);
            Map<String, String> rMap = wxPay.unifiedOrder(map, wxPaymentConfig);
            log.warn("统一下单接口返回: " + rMap);
            String return_code = rMap.get("return_code");//请求结果
            String result_code = rMap.get("result_code");//支付请求业务结果
            String return_msg = rMap.get("return_msg");
            String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
            orderModel.setPrePayId(rMap.get("prepay_id"));
            if ("SUCCESS".equals(return_code) && return_code.equals(result_code)) {
                String nonceStr = WXPayUtil.generateNonceStr();
                returnResult.put("nonceStr", nonceStr);
                String prepayid = rMap.get("prepay_id");
                returnResult.put("package", "prepay_id=" + prepayid);
                returnResult.put("signType", "MD5");
                //这边要将返回的时间戳转化成字符串，不然小程序端调用wx.requestPayment方法会报签名错误
                returnResult.put("timeStamp", timeStamp);
                //再次签名，这个签名用于小程序端调用wx.requesetPayment方法
                returnResult.put("appId", wxPaymentConfig.getAppId());
                String sign = WXPayUtil.generateSignature(returnResult, wxPaymentConfig.getPayKey());
                returnResult.put("paySign", sign);
                returnResult.put("partnerId", wxPaymentConfig.getMchID());
                System.out.println("生成的签名paySign : " + sign);
//                paymentLogService.insertPaymentLog(orderModel);
                return R.ok(returnResult);
            } else if ("201 商户订单号重复".equals(rMap.get("err_code_des"))) {
                //该订单已调用过统一下单  TODO 此处查询 用业务编号和支付标号去查 应该用的是业务id和业务类型去查询  后续开发需要着重处理
                HisPaymentLog paymentLog = paymentLogService.getByOrderNumber(orderModel.getOrderNumber());
                String nonceStr = WXPayUtil.generateNonceStr();
                returnResult.put("nonceStr", nonceStr);
                String prepayid = paymentLog.getPrePayId();
                returnResult.put("package", "prepay_id=" + prepayid);
                returnResult.put("signType", "MD5");
                //这边要将返回的时间戳转化成字符串，不然小程序端调用wx.requestPayment方法会报签名错误
                returnResult.put("timeStamp", timeStamp);
                //再次签名，这个签名用于小程序端调用wx.requesetPayment方法
                returnResult.put("appId", wxPaymentConfig.getAppId());
                String sign = WXPayUtil.generateSignature(returnResult, wxPaymentConfig.getPayKey());
                returnResult.put("paySign", sign);
                returnResult.put("partnerId", wxPaymentConfig.getMchID());
                System.out.println("生成的签名paySign : " + sign);
                return R.ok(returnResult);
            } else {
                new RuntimeException("统一下单错误:" + return_msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
           new RuntimeException("统一下单异常");
        }

        return null;
    }

    @Override
    public R alipay(OrderModel orderModel) throws Exception {
        return null;
    }


    @Override
    public String wxNativePay(WxNativePayRequest request) {
        WxPaymentConfig wxPaymentConfig = baseDictService.getDictToObj("wx_pay_config", new WxPaymentConfig());
        String body = JSONObject.toJSONString(request);
        HttpRequest post = HttpUtil.createPost("https://api.mch.weixin.qq.com/v3/pay/transactions/native");
        post.body(body);
        try {
            HashMap<String, String> returnResult = new HashMap<>();
            String nonceStr = WXPayUtil.generateNonceStr();
            returnResult.put("nonceStr", nonceStr);
            returnResult.put("package", body);
            returnResult.put("signType", "MD5");
            //这边要将返回的时间戳转化成字符串，不然小程序端调用wx.requestPayment方法会报签名错误
            String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
            returnResult.put("timeStamp", timeStamp);
            //再次签名，这个签名用于小程序端调用wx.requesetPayment方法
            returnResult.put("appId", wxPaymentConfig.getAppId());
            String sign = WXPayUtil.generateSignature(returnResult, wxPaymentConfig.getPayKey());
//            returnResult.put("paySign", sign);
//            returnResult.put("partnerId", wxPaymentConfig.getMchID());
            System.out.println("生成的签名paySign : " + sign);
//            String sign = WXPayUtil.generateSignature((Map) JSON.parse(body), wxPaymentConfig.getPayKey());
            post.header("Authorization", sign);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String response = post.execute().body();
        log.warn("微信回文：【{}】", response);
        return JSONObject.parseObject(response).getString("code_url");
    }
}
